﻿using System.Xml;

namespace XModify
{
    public class XDocument
    {
        private XmlDocument xmlDocument = null;
        private XmlNS xmlNS = null;
        private XmlNamespaceManager xmlNamespaceManager = null;

        private string xmlFileName;

        public bool SaveChanges
        {
            get;
            set;
        }

        public void Load(string xmlFileName)
        {
            xmlDocument = new XmlDocument();
            xmlDocument.Load(xmlFileName);

            xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable);
            xmlNS = XmlNSParse.Parse(xmlDocument.OuterXml, xmlNamespaceManager);

            this.xmlFileName = xmlFileName;
        }

        public XmlNode[] Select(string xPath)
        {
            xPath = XmlNSParse.NewXPath(xPath, xmlNS);
            XmlNodeList xmlNodeList = xmlDocument.SelectNodes(xPath, xmlNamespaceManager);
            if (xmlNodeList != null && xmlNodeList.Count > 0)
            {
                XmlNode[] xmlNodeArray = new XmlNode[xmlNodeList.Count];
                for (int i = 0; i < xmlNodeList.Count;i++ )
                {
                    xmlNodeArray[i] = xmlNodeList[i];
                }

                return xmlNodeArray;
            }

            return null;
        }

        public XmlNode[] NodeSelect(XmlNode xmlNode, string xPath)
        {
            xPath = XmlNSParse.NewXPath(xPath, xmlNS);
            XmlNodeList xmlNodeList = xmlNode.SelectNodes(xPath, xmlNamespaceManager);
            if (xmlNodeList != null && xmlNodeList.Count > 0)
            {
                XmlNode[] xmlNodeArray = new XmlNode[xmlNodeList.Count];
                for (int i = 0; i < xmlNodeList.Count; i++)
                {
                    xmlNodeArray[i] = xmlNodeList[i];
                }

                return xmlNodeArray;
            }

            return null;
        }

        public XmlAttribute FindAttribute(XmlAttributeCollection xmlAttributeCollection, string name)
        {
            return xmlAttributeCollection[name];
        }

        public XmlAttribute FindAttribute(XmlAttributeCollection xmlAttributeCollection, int index)
        {
            return xmlAttributeCollection[index];
        }

        public bool CheckDuplicate(XmlElement element, XmlElement child)
        {
            if (element.ChildNodes.Count > 0)
            {
                foreach (XmlElement e in element.ChildNodes)
                {
                    if (e.OuterXml == child.OuterXml)
                    {
                        return false;
                    }
                }
            }

            return true;
        }

        public XmlElement CreateElement(string name)
        {
            XmlElement xmlElement;
            if (xmlNS == null)
            {
                xmlElement = this.xmlDocument.CreateElement(name);
            }
            else
            {
                xmlElement = this.xmlDocument.CreateElement(name, xmlNS.NS);
            }

            return xmlElement;
        }

        public XmlCDataSection CreateCDataSection(string value)
        {
            return this.xmlDocument.CreateCDataSection(value);
        }

        public XmlAttribute CreateXmlAttribute(string name)
        {
            return this.xmlDocument.CreateAttribute(name);
        }

        public void Save()
        {
            this.SaveChanges = true;
        }

        internal void SaveToFile()
        {
            xmlDocument.Save(this.xmlFileName);
        }
    }
}
